package com.quanquan.user.service;

import DTO.PageDTO;
import DTO.store.StoreDTO;
import DTO.store.StoreInfoDTO;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.quanquan.user.configBeans.RabbitSender;
import com.quanquan.user.dto.IdDTO;
import com.quanquan.user.entity.IntegralTradingDetails;
import com.quanquan.user.entity.User;
import com.quanquan.user.entity.UserLevel;
import com.quanquan.user.entity.UserLevelRelationship;
import com.quanquan.user.exception.IntegralException;
import com.quanquan.user.exception.UserException;
import com.quanquan.user.repository.IntegralDetailsRepository;
import com.quanquan.user.repository.UserLevelRelationshipRepository;
import com.quanquan.user.repository.UserLevelRepository;
import com.quanquan.user.request.CalculateIntegralRequestBody;
import com.quanquan.user.request.IntegralDetailsRequestBody;
import com.quanquan.user.vo.IntegralTradingDetailsVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.core.internal.Function;
import org.springframework.data.domain.*;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import utils.*;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 功能描述:
 *
 * @ClassName: IntegralDetailsService
 * @Author: xiaoqianh丶
 * @Date: 2019-03-21 16:50
 * @Version: V1.0
 */
@Service
public class IntegralTradingDetailsService {

    private static final String STORE = "store";
    public static final String SELF_HELP = "selfHelp";
    private final IntegralDetailsRepository integralDetailsRepository;

    private final UserLevelRelationshipRepository userLevelRelationshipRepository;
    private final UserLevelService userLevelService;
    private final UserLevelRepository userLevelRepository;
    private final UserService userService;

    private final RabbitSender rabbitSender;

    private final RestTemplate restTemplate;


    @Autowired
    public IntegralTradingDetailsService(IntegralDetailsRepository integralDetailsRepository, UserService userService, RabbitSender rabbitSender, RestTemplate restTemplate, UserLevelRelationshipRepository userLevelRelationshipRepository, UserLevelRepository userLevelRepository, UserLevelService userLevelService) {
        this.integralDetailsRepository = integralDetailsRepository;
        this.userService = userService;
        this.rabbitSender = rabbitSender;
        this.restTemplate = restTemplate;
        this.userLevelRelationshipRepository = userLevelRelationshipRepository;
        this.userLevelRepository = userLevelRepository;
        this.userLevelService = userLevelService;
    }

    /**
     * 生成交易记录
     *
     * @param requestBody
     */
    public void createIntegralDetails(IntegralDetailsRequestBody requestBody) {

        IntegralTradingDetails integralTradingDetails = new IntegralTradingDetails();

        //通过映射关系来赋值 //TODO 断点看一下
        BeanUtils.copyProperties(requestBody, integralTradingDetails);

        integralTradingDetails.setCreateTime(DateUtils.currentDate());
        integralTradingDetails.setId(UUIDGenerator.getUUID());

        integralDetailsRepository.save(integralTradingDetails);

        //扣除积分（队列操作）
        //1.传入 积分数 操作动作 关联id 用户id 交易记录id
        CalculateIntegralRequestBody calculateIntegralRequestBody = new CalculateIntegralRequestBody();
        calculateIntegralRequestBody.setUserId(integralTradingDetails.getUserId());
        //通过映射关系来赋值 //TODO 断点看一下
        BeanUtil.copyProperties(requestBody, calculateIntegralRequestBody, true, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        calculateIntegralRequestBody.setIntegralDetailsId(integralTradingDetails.getId());

        try {
            calculateIntegral(calculateIntegralRequestBody);
        } catch (IntegralException e) {
            e.printStackTrace();

        }
    }



    /**
     * 结算积分并对积分明细进行余额填补
     *
     * @param requestBody
     */
    private void calculateIntegral(CalculateIntegralRequestBody requestBody) throws IntegralException {

        String userId = requestBody.getUserId();
        String integralDetailsId = requestBody.getIntegralDetailsId();
        String integralPointInfo = requestBody.getIntegralPoint();
        Integer integralPoint = Integer.valueOf(integralPointInfo);
        Integer tradeAction = requestBody.getTradeAction();

        //扣除积分
        String integralBalance = userService.settlementOfIntegral(userId, integralPoint, tradeAction);
        if (StringUtils.isEmpty(integralBalance)) {
            throw new IntegralException("余额不足");
        }

        Map<String, Object> properties = new HashMap<>();
        properties.put("integralBalance", integralBalance);
        properties.put("integralDetailsId", integralDetailsId);
        properties.put("tradeAction", tradeAction);

        //将计算结果放到MQ队列去补充明细的余额
        String msg = "补全积分明细余额";
        String exchange = "integral.exchange";
        String routingKey = "integralBalance.completion";
        rabbitSender.sendMessageToMQ(msg, properties, exchange, routingKey);
    }


    /**
     * 根据积分明细id查出对应的积分记录
     * 补全积分明细余额
     * 发消息推送rabbitMq
     *
     * @param integralDetailsId
     * @param integralBalance
     */
    public void updateIntegralBalance(String integralDetailsId, String integralBalance) {
        IntegralTradingDetails integralDetails = getIntegralTradingDetails(integralDetailsId);
        assert integralDetails != null;
        integralDetails.setIntegrBalalance(integralBalance);
        integralDetailsRepository.save(integralDetails);

        //发送消息推送
        Map<String, Object> properties = new HashMap<>();
        properties.put("integralBalance", integralBalance);
        properties.put("userId", integralDetails.getUserId());
        properties.put("tradingContent", integralDetails.getTradingContent());
        properties.put("tradeAction", integralDetails.getTradeAction());
        properties.put("integralPoint", integralDetails.getIntegralPoint());
        properties.put("foreignKeyId", integralDetails.getForeignKeyId());
        properties.put("consumeType", integralDetails.getConsumeType());
        properties.put("createTime", integralDetails.getCreateTime());


        //将计算结果放到MQ队列去补充明细的余额
        String msg = "发消息推送积分变动";
        String exchange = "send.exchange";
        String routingKey = "send.message";
//        rabbitSender.sendMessageToMQ(msg, properties, exchange, routingKey);
    }

    /**
     * 根据积分明细id查询积分
     *
     * @param integralDetailsId
     * @return
     */
    private IntegralTradingDetails getIntegralTradingDetails(String integralDetailsId) {
        IntegralTradingDetails integralDetails = integralDetailsRepository.findById(integralDetailsId).orElse(null);
        //todo 有待考虑是否在service层捕获
        if (integralDetails == null) {
            try {
                throw new IntegralException("该条积分明细已经不存在");
            } catch (IntegralException e) {
                e.printStackTrace();
            }
        }
        return integralDetails;
    }

    /**
     * 计算会员积分消耗总额，提升会员等级
     *
     * @param integralDetailsId
     */
    public void countIntegral(String integralDetailsId) throws IntegralException {
        IntegralTradingDetails integralDetails = getIntegralTradingDetails(integralDetailsId);
        assert integralDetails != null;
        String createTime = integralDetails.getCreateTime();
        String userId = integralDetails.getUserId();
        String joinDate = null;
        int newMember = 0;
        try {
            User user = userService.getUserById(userId);
            joinDate = user.getJoinDate();
            newMember = user.getNewMember();
        } catch (UserException e) {
            e.printStackTrace();
        }

        //会员等级关系对象
        UserLevelRelationship userLevelRelationship = userLevelRelationshipRepository.findUserLevelRelationshipByUserIdAndRemove(userId, 0);
        //会员等级id
        String userLevelId = userLevelRelationship.getUserLevelId();
        //最上级等级
        List<UserLevel> list = userLevelRepository.findAllByRemoveOrderByLevelStratumDesc(0);
        UserLevel userLevelMax = list.get(0);
        Integer levelStratumMax = Integer.parseInt(userLevelMax.getIntegralTotal());
        //会员当前等级对象
        UserLevel userLevel = userLevelRepository.findUserLevelByIdAndRemove(userLevelId, 0);
        //会员下一级对象（如果是最高级就不用判断了）
        Integer levelStratum = userLevel.getLevelStratum();
        //当前等级的上一级
        UserLevel userUpLevel = null;
        if (levelStratum == 1) {
            userUpLevel = userLevelService.findUserLevelByLevelStratum(2);
            if (userLevel == null) {
                throw new IntegralException("会员等级层级不对");
            }

        }
        if (levelStratum == 2) {
            userUpLevel = userLevelService.findUserLevelByLevelStratum(3);
            if (userLevel == null) {
                throw new IntegralException("会员等级层级不对");
            }
        }
        if (levelStratum == 3) {
            return;
        }

        Calendar nowTime = Calendar.getInstance();
        Date startDate = null;
        Date endDate = null;
        //判断是否老用户，老用户(规则跟新用户不一样)
        if (levelStratum < 2) {

            List<IntegralTradingDetails> integralTardingByTime = new ArrayList();
            //判断当前月在那个日期分段内

            // 如果等级是1小票消费当天往前90天

            startDate = CalendarUtil.getAfterDayDate("-89", new Date());
            endDate = new Date();
            String starTime = DateUtils.dateToString(startDate, "yyyy-MM-dd HH:mm:ss");
            String endTime = DateUtils.dateToString(endDate, "yyyy-MM-dd HH:mm:ss");
            integralTardingByTime = findIntegralTardingByTime(starTime, endTime, userId);

            List<String> integralTradings = integralTardingByTime.stream().filter(i -> i.getTradeAction() == 0).map(i -> i.getIntegralPoint()).collect(Collectors.toList());
            long count = integralTradings.stream().map(Integer::parseInt).mapToInt(i -> i).sum();
            //根据时间节点查询获得的积分记录

            int integralTotal = Integer.parseInt(userUpLevel.getIntegralTotal());
            //乐享尊卡
            if (count >= integralTotal && userLevel.getLevelStratum() == 1) {
                //时间比较

                userLevelService.upgradeLevel(userId, levelStratum);
                if (count >= levelStratumMax) {
                    ++levelStratum;
                    userLevelService.upgradeLevel(userId, levelStratum);
                }
            }
        } else if (levelStratum == 2) {

            List<IntegralTradingDetails> integralTardingByTime = new ArrayList();
            //判断当前月在那个日期分段内
            startDate = CalendarUtil.getAfterDayDate("-179", new Date());
            endDate = new Date();
            String starTime = DateUtils.dateToString(startDate, "yyyy-MM-dd HH:mm:ss");
            String endTime = DateUtils.dateToString(endDate, "yyyy-MM-dd HH:mm:ss");
            integralTardingByTime = findIntegralTardingByTime(starTime, endTime, userId);

            List<String> integralTradings = integralTardingByTime.stream().filter(i -> i.getTradeAction() == 0).map(i -> i.getIntegralPoint()).collect(Collectors.toList());
            long count = integralTradings.stream().map(Integer::parseInt).mapToInt(i -> i).sum();
            //根据时间节点查询获得的积分记录

            int integralTotal = Integer.parseInt(userUpLevel.getIntegralTotal());
            //乐享星卡
            if (count >= integralTotal && userLevel.getLevelStratum() == 2) {
                //时间比较
                userLevelService.upgradeLevel(userId, levelStratum);

            }
        }
//        else {
//            //用户的所有积分明细
//            List<IntegralTradingDetails> integralTradingList = findAllUserIntegralTrading(userId);
//
//            List<String> integralTradings = integralTradingList.stream().filter(i -> i.getTradeAction() == 0).map(i -> i.getIntegralPoint()).collect(Collectors.toList());
//            //用户到现在为止的获得的积分总额
//            int count = integralTradings.stream().map(Integer::parseInt).mapToInt(i -> i).sum();
//            // 先实现新用户的
//            //入会时间加3个月
//            Date joinTime = DateUtils.parseStr2Date("yyyy-MM-dd", joinDate);
//            Calendar calendar = Calendar.getInstance();
//            calendar.setTime(joinTime);
//
//
//            int integralTotal = Integer.parseInt(userUpLevel.getIntegralTotal());
//            //乐享尊卡
//            if (count >= integralTotal && userLevel.getLevelStratum() == 1) {
//                calendar.add(Calendar.MONTH, +3);
//                //时间比较
//                if (nowTime.before(calendar)) {
//                    userLevelService.upgradeLevel(userId, levelStratum);
//                    if (count >= levelStratumMax) {
//                        ++levelStratum;
//                        userLevelService.upgradeLevel(userId, levelStratum);
//                    }
//                }
//            }
//            //乐享星卡
//            if (count >= integralTotal && userLevel.getLevelStratum() == 2) {
//                calendar.add(Calendar.MONTH, +6);
//                //时间比较
//                if (nowTime.before(calendar)) {
//                    userLevelService.upgradeLevel(userId, levelStratum);
//
//                }
//            }
//        }


    }

    /**
     * 根据用户id查询所有消费记录
     *
     * @param userId
     * @return
     */
    private List<IntegralTradingDetails> findAllUserIntegralTrading(String userId) {
        List<IntegralTradingDetails> integralTradingList = integralDetailsRepository.findIntegralTradingDetailsByUserId(userId);
        if (integralTradingList.size() <= 0) {
            try {
                throw new IntegralException("该用户积分消费记录不存在");
            } catch (IntegralException e) {
                e.printStackTrace();
            }
        }
        return integralTradingList;
    }

    public PageDTO<IntegralTradingDetailsVO> findIntegralTrading(IntegralDetailsRequestBody requestBody) throws IntegralException {
        String from = requestBody.getFromDate();
        String to = requestBody.getToDate();
        Integer page = requestBody.getPage() == null ? 0 : requestBody.getPage();
        Integer size = requestBody.getSize() == null ? 10 : requestBody.getSize();
        String sortBy = StringUtil.isNotEmpty(requestBody.getSort()) ? requestBody.getSort() : "createTime";
        Sort sort;
        Integer action = requestBody.getTradeAction();
        String keyword = requestBody.getKeyword();
        String storeName = requestBody.getStoreName();
        String consumeType = requestBody.getConsumeType();


        //根据前端传来的关键词查询
        if (requestBody.isAsc()) {
            sort = new Sort(Sort.Direction.ASC, sortBy);
        } else {
            sort = new Sort(Sort.Direction.DESC, sortBy);
        }
        //分页查询所有申请记录
        Pageable pageable = PageRequest.of(page, size, sort);
        Page<IntegralTradingDetails> paged = integralDetailsRepository.findAll((Specification<IntegralTradingDetails>) (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (null != action) {
                predicates.add(cb.equal(root.get("tradeAction").as(Integer.class), action));
            }
            if (StringUtil.isNotEmpty(keyword)) {
                List<User> finalListByKeyword = userService.findListByKeyword(keyword);
                if (null != finalListByKeyword && finalListByKeyword.size() > 0) {
                    CriteriaBuilder.In<String> in = cb.in(root.get("userId"));
                    finalListByKeyword.forEach(user -> in.value(user.getId()));
                    Predicate p = cb.or((cb.like(root.get("orderNum").as(String.class), "%" + keyword + "%")), in);
                    predicates.add(p);
                } else {
                    Predicate p1 = cb.like(root.get("orderNum").as(String.class), "%" + keyword + "%");
                    Predicate p2 = cb.or(cb.like(root.get("tradingContent").as(String.class), "%" + keyword + "%"), p1);

                    predicates.add(p2);
                }
            }
            if (StringUtil.isNotEmpty(consumeType)) {
                predicates.add(cb.equal(root.get("consumeType").as(String.class), consumeType));
            }

            if (StringUtil.isNotEmpty(storeName)) {
                IdDTO idDTO1 = new IdDTO();
                idDTO1.setKeyWord(storeName);
                StoreInfoDTO storeInfoDTO1 = restTemplate.postForObject("http://QUANQUAN-STORE/store/page_find_store", idDTO1, StoreInfoDTO.class);
                List<StoreDTO> stores = storeInfoDTO1.getStoreDTOS();
                StoreDTO storeDTO = stores.get(0);
                predicates.add(cb.equal(root.get("foreignKeyId").as(String.class), storeDTO.getId()));
            }

            if (StringUtil.isNotEmpty(from)) {
                Date startOfDay = DateUtils.getStartOfDay(DateUtils.strToDate(from, DateUtils.DATE));

                predicates.add(cb.greaterThanOrEqualTo(root.get("createTime").as(Date.class), startOfDay));
            }
            if (StringUtil.isNotEmpty(to)) {
                Date endOfDay = DateUtils.getEndOfDay(DateUtils.strToDate(to, DateUtils.DATE));
                predicates.add(cb.lessThanOrEqualTo(root.get("createTime").as(Date.class), endOfDay));
            }
            return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
        }, pageable);
        List<IntegralTradingDetails> integralTradingDetailsList = paged.getContent();
        //1.使用java8新特新Stream 按条件（积分的来源） 取出所有的foreignKeyId (去重) 放到集合或数组中
        //2.将拿到的所有外建发送http请求去商户模块或其他模块去调取数据
        //3.将返回的数据与当前模块的数据进行结合(视图)
        //todo 暂时只考虑商户 如有新的类型直接将改逻辑抽取成方法()
        //根据comsumType把list转成Map
        Map<String, List<IntegralTradingDetails>> map = integralTradingDetailsList.parallelStream().
                filter(distinctByKey(IntegralTradingDetails::getForeignKeyId)).
                collect(Collectors.groupingBy(IntegralTradingDetails::getConsumeType));

        List<String> storeForeignKeyIds = new ArrayList<>();
        List<String> storeForeignKeyIdsBySelfHelp = new ArrayList<>();
        if (null != map && map.size() > 0) {
            List<IntegralTradingDetails> selfHelp = map.get(SELF_HELP);
            if (null != selfHelp && selfHelp.size() > 0) {
                storeForeignKeyIdsBySelfHelp = selfHelp.stream().
                        map(IntegralTradingDetails::getForeignKeyId).
                        collect(Collectors.toList());
            }
            List<IntegralTradingDetails> store = map.get(STORE);
            if (null != store && store.size() > 0) {
                storeForeignKeyIds = store.stream().
                        map(IntegralTradingDetails::getForeignKeyId).
                        collect(Collectors.toList());
            }
        }
        storeForeignKeyIds.addAll(storeForeignKeyIdsBySelfHelp);

        //集合去重
        List<String> list = removeDuplicate(storeForeignKeyIds);

        IdDTO idDTO = new IdDTO();
        idDTO.setForeignKeyIds(list);

        StoreInfoDTO storeInfoDTO = restTemplate.postForObject("http://QUANQUAN-STORE/store/query_by_id_list", idDTO, StoreInfoDTO.class);
        List<StoreDTO> storeDTOS = storeInfoDTO.getStoreDTOS();

        //取出查到的积分记录的userId
        Set<String> userIds = integralTradingDetailsList.parallelStream().
                filter(distinctByKey(IntegralTradingDetails::getUserId)).
                map(IntegralTradingDetails::getUserId).collect(Collectors.toSet());

        List<User> users = userService.findUsers(userIds);

        //将积分明细实体映射到VO集合上
        List<IntegralTradingDetailsVO> integralTradingDetailsVOS = integralTradingDetailsList.parallelStream().map(e -> new IntegralTradingDetailsVO(
                e.getId(),
                e.getOrderNum(),
                e.getCreateTime(),
                e.getTradingContent(),
                e.getTradeAction(),
                e.getIntegralPoint(),
                e.getConsumeType(),
                e.getIntegrBalalance(),
                e.getForeignKeyId(),
                e.getUserId(),
                null,
                null, null, null, null)).
                collect(Collectors.toList());

        //将积分的关于商户的信息补上
        for (StoreDTO storeDTO : storeDTOS) {
            for (IntegralTradingDetailsVO integralTradingDetailsVO : integralTradingDetailsVOS) {
                if ((storeDTO.getId()).equals(integralTradingDetailsVO.getForeignKeyId())) {
                    integralTradingDetailsVO.setStoreName(storeDTO.getStoreName());
                    integralTradingDetailsVO.setStoreCommercial(storeDTO.getStoreCommercial());
                }
            }

        }


        //将积分的关于用户的信息补上
        for (User user : users) {
            for (IntegralTradingDetailsVO integralTradingDetailsVO : integralTradingDetailsVOS) {
                if ((user.getId()).equals(integralTradingDetailsVO.getUserId())) {
                    integralTradingDetailsVO.setMemberCardNum(user.getMemberCardNum());
                    integralTradingDetailsVO.setPhone(user.getPhone());
                    integralTradingDetailsVO.setMemberName(user.getMemberName());
                }
            }
        }

        PageDTO<IntegralTradingDetailsVO> pageDTO = new PageDTO<>();
        pageDTO.setTotal(paged.getTotalElements());
        pageDTO.setList(integralTradingDetailsVOS);
        pageDTO.setTotalPage(paged.getTotalPages());
        pageDTO.setPage(page);
        pageDTO.setPageSize(size);
        pageDTO.setFromDate(from);
        pageDTO.setToDate(to);
        pageDTO.setKeyword(keyword);
        pageDTO.setStoreName(storeName);
        pageDTO.setConsumeType(consumeType);
        return pageDTO;

    }

    private static <T> java.util.function.Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Set<Object> seen = ConcurrentHashMap.newKeySet();
        return t -> seen.add(keyExtractor.apply(t));
    }

    /**
     * 查询个人消费积分明细
     *
     * @param userId
     * @return
     */
    public List<IntegralTradingDetails> findPersionalIntegralTradingDetails(String userId, Integer tradeAction, Integer page, Integer size, String years) {
//分页查询所有申请记录
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");

        Pageable pageable = PageRequest.of(page, size, sort);
        if (StringUtils.isNotEmpty(years)) {
            Page<IntegralTradingDetails> integralTradingDetails = integralDetailsRepository.findAll((Specification<IntegralTradingDetails>) (root, query, criteriaBuilder) -> {
                List<javax.persistence.criteria.Predicate> predicates = new ArrayList<javax.persistence.criteria.Predicate>();
                // 创建具体查询条件

                if (org.apache.commons.lang.StringUtils.isNotEmpty(years)) {
                    predicates.add(criteriaBuilder.like(root.get("createTime").as(String.class), "%" + years + "%"));
                }
                if (org.apache.commons.lang.StringUtils.isNotEmpty(userId)) {

                    predicates.add(criteriaBuilder.equal(root.get("userId"), userId));
                }

                if (tradeAction != 3) {

                    predicates.add(criteriaBuilder.equal(root.get("tradeAction"), tradeAction));
                }

                return query.where(predicates.toArray(new javax.persistence.criteria.Predicate[predicates.size()])).getRestriction();
            }, pageable);
            return integralTradingDetails.getContent();
        } else {
            IntegralTradingDetails tradingDetails = new IntegralTradingDetails();
            if (tradeAction != 3) {
                tradingDetails.setTradeAction(tradeAction);
            }
            tradingDetails.setUserId(userId);
            Example<IntegralTradingDetails> example = Example.of(tradingDetails);
            Page<IntegralTradingDetails> findAll = integralDetailsRepository.findAll(example, pageable);
            if ((findAll.getSize()) == 0) {
                return null;
            }
            return findAll.getContent();
        }


    }

    public List<IntegralTradingDetails> findYearsIntegralTrading(String userId, String years) {
        return integralDetailsRepository.findAll((Specification<IntegralTradingDetails>) (root, query, criteriaBuilder) -> {
            List<javax.persistence.criteria.Predicate> predicates = new ArrayList<javax.persistence.criteria.Predicate>();
            // 创建具体查询条件

            if (org.apache.commons.lang.StringUtils.isNotEmpty(years)) {
                predicates.add(criteriaBuilder.like(root.get("createTime").as(String.class), "%" + years + "%"));
            }
            if (org.apache.commons.lang.StringUtils.isNotEmpty(userId)) {

                predicates.add(criteriaBuilder.equal(root.get("userId"), userId));
            }


            return query.where(predicates.toArray(new javax.persistence.criteria.Predicate[predicates.size()])).getRestriction();
        });
    }


    public static List removeDuplicate(List list) {
        HashSet h = new HashSet(list);
        list.clear();
        list.addAll(h);
        return list;
    }


    /**
     * 自动提升等级专用查询个人记录
     *
     * @param starTime
     * @param endTime
     * @return
     */
    public List<IntegralTradingDetails> findIntegralTardingByTime(String starTime, String endTime, String userId) {

        //分页查询所有申请记录
        List<IntegralTradingDetails> paged = integralDetailsRepository.findAll((Specification<IntegralTradingDetails>) (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();

            if (StringUtil.isNotEmpty(starTime)) {
                Date startOfDay = DateUtils.getStartOfDay(DateUtils.strToDate(starTime, DateUtils.DATE));

                predicates.add(cb.greaterThanOrEqualTo(root.get("createTime").as(Date.class), startOfDay));
            }
            if (StringUtil.isNotEmpty(endTime)) {
                Date endOfDay = DateUtils.getEndOfDay(DateUtils.strToDate(endTime, DateUtils.DATE));
                predicates.add(cb.lessThanOrEqualTo(root.get("createTime").as(Date.class), endOfDay));
            }
            predicates.add(cb.equal(root.get("tradeAction"), 0));
            predicates.add(cb.equal(root.get("userId"), userId));
            return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
        });

        return paged;
    }



}
